/**
 * This file is part of the NatCrackerToolbox.
 * 
 * Copyright (C) 2009 - 2011 Peerialism Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 **/
package com.peerialism.natcracker.discovery;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;

import com.peerialism.natcracker.common.GatewayDevice;
import com.peerialism.natcracker.common.GatewayDevice.GatewayType;


public class DiscoveryInfoBehave {
	private final InetAddress testIP;
	private boolean error = false;
	private int errorResponseCode = 0;
	private String errorReason;
	private boolean openAccess = false;
	private boolean blockedUDP = false;
	private boolean natted = false;
	private final GatewayDevice natDevice;
	private InetAddress publicIP;
	private int localPort;

	// private final boolean notConnected = false;
	public DiscoveryInfoBehave(InetAddress testIP) {
		this.testIP = testIP;
		natDevice = new GatewayDevice();
	}

	public boolean isError() {
		return error;
	}

	public void setError(int responseCode, String reason) {
		error = true;
		errorResponseCode = responseCode;
		errorReason = reason;
	}

	public boolean isOpenAccess() {
		if (error)
			return false;
		return openAccess;
	}

	public void setOpenAccess() {
		this.natDevice.setGatewayType(GatewayType.OpenInternet);
		openAccess = true;
	}

	public boolean isBlockedUDP() {
		if (error)
			return false;
		return blockedUDP;
	}

	public void setBlockedUDP() {
		blockedUDP = true;
	}

	public InetAddress getPublicIP() {
		return publicIP;
	}

	public InetAddress getLocalIP() {
		return testIP;
	}

	public void setPublicIP(InetAddress publicIP) {
		this.publicIP = publicIP;
	}

	public boolean isNatted() {
		return natted;
	}

	public void setNatted(boolean natted) {
		this.natDevice.setGatewayType(GatewayType.NAT);
		this.natted = natted;
	}

	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("Network interface: ");
		try {
			sb.append(NetworkInterface.getByInetAddress(testIP).getName());
		} catch (SocketException se) {
			sb.append("unknown");
		}
		sb.append(", ");
		sb.append("Local IP address: ");
		sb.append(testIP.getHostAddress());
		sb.append(", ");
		if (error) {
			sb.append(errorReason + " - Responsecode: " + errorResponseCode);
			return sb.toString();
		}
		sb.append("Result: ");
		if (openAccess)
			sb.append("Open access to the Internet, ");
		if (blockedUDP)
			sb.append("Firewall blocks UDP, ");
		if (natted)
			sb.append("Natted, ");
		if (!openAccess && !blockedUDP && !natted)
			sb.append("unknown, ");
		sb.append("Public IP address: ");
		if (publicIP != null) {
			sb.append(publicIP.getHostAddress() + ", ");
		} else {
			sb.append("unknown, ");
		}
		if (natted) {
			sb.append("NAT Device: ");
			if (natDevice != null) {
				sb.append(natDevice.toLongString());
			} else {
				sb.append("unknown");
			}
		}
		return sb.toString();
	}

	public GatewayDevice getNatDevice() {
		return natDevice;
	}

	public void setLocalPortUsed(int localPort) {
		this.localPort = localPort;
	}

	public int getLocalPortUsed() {
		return localPort;
	}
}
